home *** CD-ROM | disk | FTP | other *** search
/ Ian & Stuart's Australian Mac 1993 September / September 93.iso / Archives / Utilities / Text / wordcount / WordCount.c < prev    next >
C/C++ Source or Header  |  1992-12-11  |  3KB  |  151 lines

  1. /*
  2.  * WordCount.c
  3.  *
  4.  * BBEdit extension by
  5.  * Kamal Abdali, P.O. Box 65207, Washington, DC 20035.
  6.  * December 1992
  7.  *
  8.  * Displays the number of sentences, paragrphs, nonempty lines,
  9.  * words, and characters in the selection.
  10.  * If the selection is null, the info is for the whole file.
  11.  *
  12.  * To create this extension in THINK C, include this file and MacTraps
  13.  * in the project, build as a code resource with WordCount.Rsrc,
  14.  * and put the resource in the BBEdit extension folder.
  15.  * 
  16.  */
  17.  
  18. #include <Packages.h>     /* For NumToString */
  19. #include <SetupA4.h>
  20. #include "ExternalInterface.h"
  21.  
  22.  
  23. /* Dialog ID & DITL item numbers */
  24.  
  25. #define kDlg    128
  26. enum    {iOK = 1, iSeparator = 3, iPara, iSentence, iLine, iWord, iChar};
  27.  
  28. long    paraCount = 0;    
  29. long    sentenceCount = 0;
  30. long    lineCount = 0;
  31. long    wordCount = 0;
  32. long    charCount = 0;
  33.  
  34. #define WordEnd(c) ((c == ' ') || (c == '\t'))
  35. #define LineEnd(c) ((c == '\n') || (c == '\r'))
  36. #define SentenceEnd(c) ((c == '.') || (c == '!') || (c == '?'))
  37.  
  38.  
  39. static long get_handle_size(Handle h)
  40. {
  41.     asm {
  42.         movea.l    h, a0
  43.         _GetHandleSize
  44.     }
  45. }
  46.  
  47.  
  48. static void SetCountStr(DialogPtr dPtr, short itemNo, long count)
  49. {
  50.     Handle    itemHdl;
  51.     short    type;
  52.     Rect    rect;
  53.     unsigned char str[16];
  54.  
  55.     GetDItem(dPtr, itemNo, &type, &itemHdl, &rect);
  56.     NumToString(count, str);
  57.     SetIText(itemHdl, str);
  58. }
  59.  
  60.  
  61. static void WordCount(ExternalCallbackBlock *callbacks, WindowPtr w)
  62. {
  63.     Handle    text;
  64.     Size    size;
  65.     long    selStart, selEnd, firstChar, i;
  66.     Boolean    paraEndFound, sentenceEndFound, lineEndFound, wordEndFound;
  67.     char    ch, prevCh;
  68.  
  69.     text = callbacks->GetWindowContents(w);
  70.     size = get_handle_size(text);
  71.     callbacks->GetSelection(&selStart, &selEnd, &firstChar);        
  72.     if (selStart == selEnd) {
  73.         selStart = 0;
  74.         selEnd = size;
  75.     }        
  76.     
  77.     wordEndFound = lineEndFound = true;
  78.     sentenceEndFound = paraEndFound = false;
  79.     ch = ' ';
  80.     for (i = selStart; i < selEnd; i++) {
  81.         prevCh = ch;
  82.         ch = (*text)[i];
  83.         if (WordEnd(ch)) {
  84.             wordEndFound = true;
  85.         } else if (LineEnd(ch)) {
  86.             lineEndFound = wordEndFound = true;
  87.             if (LineEnd(prevCh))
  88.                 paraEndFound =true;
  89.         } else if (SentenceEnd(ch)) {
  90.             sentenceEndFound = true;
  91.         } else {
  92.             if (wordEndFound) {
  93.                 wordEndFound = false;
  94.                 wordCount++;
  95.             }
  96.             if (lineEndFound) {
  97.                 lineEndFound = false;
  98.                 lineCount++;
  99.             }
  100.             if (sentenceEndFound) {
  101.                 sentenceEndFound = false;
  102.                 if (!SentenceEnd(prevCh))
  103.                     sentenceCount++;
  104.             }
  105.             if (paraEndFound) {
  106.                 paraEndFound = false;
  107.                 paraCount++;
  108.             }
  109.         }
  110.     }
  111.     if (sentenceEndFound)
  112.         sentenceCount++;
  113.     paraCount++;
  114.     charCount = selEnd - selStart;
  115. }
  116.  
  117.  
  118. static void Report(ExternalCallbackBlock *callbacks)
  119. {
  120.     DialogPtr    dPtr;
  121.     GrafPtr        savePort;
  122.     short        item;
  123.  
  124.     GetPort(&savePort);
  125.     dPtr = callbacks->CenterDialog(kDlg);
  126.     SetPort(dPtr);
  127.     callbacks->FrameDialogItem(dPtr, iSeparator);
  128.     SetCountStr(dPtr, iPara, paraCount);
  129.     SetCountStr(dPtr, iSentence, sentenceCount);
  130.     SetCountStr(dPtr, iLine, lineCount);
  131.     SetCountStr(dPtr, iWord, wordCount);
  132.     SetCountStr(dPtr, iChar, charCount);
  133.     do
  134.         ModalDialog(callbacks->StandardFilter, &item);
  135.     while (item != iOK);
  136.     DisposDialog(dPtr);
  137.     SetPort(savePort);        
  138. }
  139.  
  140.  
  141. pascal void main(ExternalCallbackBlock *callbacks, WindowPtr w)
  142. {        
  143.     RememberA0();
  144.     SetUpA4();    
  145.     if (w && callbacks->version >= 2) {
  146.         WordCount(callbacks, w);
  147.         Report(callbacks);
  148.     }    
  149.     RestoreA4();
  150. }
  151.